package composer.base;

import java.util.Vector;

import javax.microedition.media.control.MIDIControl;

public class NotesOnThread extends Thread {

	private Note[] notes;

	private byte[] channels;

	private long milisPerBeat;

	private MIDIControl midiControl;

	public NotesOnThread(Vector tracks, MIDIControl midiControl, int sbpm) {
		this.milisPerBeat = (1000 * 60) / sbpm;
		this.midiControl = midiControl;

		int numberOfNotes = 0;
		for (int i = 0; i < tracks.size(); i++) {
			numberOfNotes += ((Track) tracks.elementAt(i)).getNotes().size();
		}
		this.notes = new Note[numberOfNotes];
		this.channels = new byte[numberOfNotes];

		int counter = 0;
		for (int i = 0; i < tracks.size(); i++) {
			Track track = ((Track) tracks.elementAt(i));
			for (int j = 0; j < track.getNotes().size(); j++) {
				notes[counter] = (Note) track.getNotes().elementAt(j);
				channels[counter] = track.getChannel();
				counter++;
			}
		}

		for (int i = 0; i < this.notes.length; i++) {
			for (int j = i + 1; j < this.notes.length; j++) {
				if (this.notes[i].getPosition() > this.notes[j].getPosition()) {
					Note temp = this.notes[i];
					this.notes[i] = this.notes[j];
					this.notes[j] = temp;

					byte tmpChannel = this.channels[i];
					this.channels[i] = this.channels[j];
					this.channels[j] = tmpChannel;
				}
			}
		}
	}

	public void run() {
		System.out.println("running notes on thread.");
		long songStartTime = System.currentTimeMillis();
		int counter = 0;
		while (counter < this.notes.length) {
			long noteStartTime = this.notes[counter].getPosition() * this.milisPerBeat;
			long elapsed = System.currentTimeMillis() - songStartTime;
			
			try {
				if(noteStartTime > elapsed)
					Thread.sleep(noteStartTime - elapsed);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e){
				e.printStackTrace();
				System.out.println("erro em Thread.sleep. Argument = " + (noteStartTime - elapsed));
			}
			
			try {
				midiControl.shortMidiEvent(MIDIControl.NOTE_ON
						| (int) this.channels[counter], this.notes[counter]
						.getTone(), this.notes[counter].getIntensity());
			} catch (Throwable t) {
				System.out.println("erro no shorMidiEvent" +
						"\n\tchannel = "+(int) this.channels[counter]+
						"\n\tnote = " + this.notes[counter].getTone() +   
						"\n\tintensity = " + this.notes[counter].getIntensity());
			}
			counter = counter + 1;
		}
	}

}
